/***************************************************************************
 *   Copyleft 2006-2007 by												   *
 *	 Iwanicki Krzysztof													   *
 *   <gamma.mini.pw.edu.pl/~iwanickik>									   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 ***************************************************************************/
#include "./PointsSetManager.h"
#include "../Engine3D.h"
#include "../../resource.h"

/**************************************************************
* Constructors                                                *
***************************************************************/
PointsSetManager::PointsSetManager(Cursor3D* cursor, PointsSet* pointsSet):
		Cursor3DManager(cursor) { 
	mSelectedPoint = -1;
	mObject = pointsSet;
}

    
/**************************************************************
* Operators                                                   *
***************************************************************/


/**************************************************************
* Other helpful functions                                     *
***************************************************************/
cVoid PointsSetManager::DeselectPoint() {
	if (mSelectedPoint != -1) {
		PointsSet* points = (PointsSet*) mObject;
		points->DeselectPoints();
		mSelectedPoint = -1;
	}
}

cVoid PointsSetManager::SelectPoint() {
	if (mSelectedPoint != -1) {
		PointsSet* points = (PointsSet*) mObject;
		points->SelectPoint(mSelectedPoint, PointsSet::PERS_SELECTION);
	}
}

cVoid PointsSetManager::FindPoint(cBool bRemember) {
	PointsSet* points = (PointsSet*) mObject;
	Point4D p = mCursor->GetWorldPosition();

	for (cInt i = 0; i < points->GetNrOfPoints(); i++) {
		if ((points->GetPoint(i) - p).Abs() <= 10.0f) {
			PointsSet::SELECTION_TYPE eType = points->SelectPoint(i, bRemember);
			if (eType == PointsSet::PERS_SELECTION) {
				if (mSelectedPoint != -1) {
					points->SelectPoint(mSelectedPoint, !bRemember);
				}
				mSelectedPoint = i;
			} else {
				mSelectedPoint = -1;
			}
		} 
	}
}

cVoid PointsSetManager::FindPoint() {
	PointsSet* points = (PointsSet*) mObject;
	Point4D p = mCursor->GetWorldPosition();

	for (cInt i = 0; i < points->GetNrOfPoints(); i++) {
		if ((points->GetPoint(i) - p).Abs() <= 10.0f) {
			points->SelectPoint(i, PointsSet::TEMP_SELECTION);
		} else {
			points->SelectPoint(i, PointsSet::NO_SELECTION);
		}
	}
}

/*virtual*/ cVoid PointsSetManager::OnCommand(HWND hwnd, WPARAM wParam, LPARAM lParam, Engine3D* engine) {	
	cUShort cmd = LOWORD(wParam);
	
	if (mObject) {
		switch(cmd) {
			case ID_DEL_POINT: {
					if (mSelectedPoint != -1) {
						PointsSet* points = (PointsSet*) mObject;
						points->RemovePoint(mSelectedPoint);
						mSelectedPoint = -1;
					}
					break;
				}
			case ID_ROTTXA:
				engine->mScene->Transform(Matrix4D::RotationX(-5.0f));
				break;
			case ID_ROTTXQ:
				engine->mScene->Transform(Matrix4D::RotationX(5.0f));
				break;
			case ID_ROTTYS:
				engine->mScene->Transform(Matrix4D::RotationY(-5.0f));
				break;
			case ID_ROTTYW:
				engine->mScene->Transform(Matrix4D::RotationY(5.0f));
				break;
			case ID_ROTTZD:
				engine->mScene->Transform(Matrix4D::RotationZ(-5.0f));
				break;
			case ID_ROTTZE:
				engine->mScene->Transform(Matrix4D::RotationZ(5.0f));
				break;
			case ID_TRANSIZ:
				engine->mScene->Transform(Matrix4D::Translation(Point4D(0.0f, 0.0f, 10.0f)));
				break;
			case ID_TRANSDZ:
				engine->mScene->Transform(Matrix4D::Translation(Point4D(0.0f, 0.0f, -10.0f)));
				break;
			case ID_DESELECTPOINTS:
				DeselectPoint();
				break;
			case ID_SHOWHIDEPOINTSCORDS: {
					PointsSet* points = (PointsSet*) mObject;
					points->SwitchDisplayPoints();
				}
				break;
			default:
				break;
		}
	}
}

/*virtual*/ cVoid PointsSetManager::OnMouseMove(cPoint point, Engine3D* engine) {
	Cursor3DManager::OnMouseMove(point, engine);
	if (mLBDown && mSelectedPoint != -1) {
		PointsSet* points = (PointsSet*) mObject;
		points->ReplacePoint(mCursor->GetWorldPosition(), mSelectedPoint);
	} else {
		FindPoint();
	}
}

/*virtual*/ cVoid PointsSetManager::OnMouseWheel(cInt iDelta, Engine3D* engine) {
	Cursor3DManager::OnMouseWheel(iDelta, engine);
	FindPoint();
}

/*virtual*/ cVoid PointsSetManager::OnLeftMouseDown(cPoint point, Engine3D* engine) {
	InputManager::OnLeftMouseDown(point, engine);	
}

/*virtual*/ cVoid PointsSetManager::OnLeftMouseUp(cPoint point, Engine3D* engine) {
	InputManager::OnLeftMouseUp(point, engine);
	FindPoint(true);
}

/*virtual*/ cVoid PointsSetManager::OnRightMouseDown(cPoint point, Engine3D* engine) {
	InputManager::OnRightMouseDown(point, engine);
	((PointsSet*) mObject)->AddPoint(mCursor->GetWorldPosition());
}